package com.baoyouqun.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baoyouqun.base.utils.ConvertUtils;
import com.baoyouqun.base.utils.ExcelTool;
import com.baoyouqun.domain.CreateCmd.CityPartnerApplicationCreateCmd;
import com.baoyouqun.domain.Query.CityPartnerApplicationQuery;
import com.baoyouqun.domain.UpdateCmd.CityPartnerApplicationUpdateCmd;
import com.baoyouqun.domain.VO.CityPartnerApplicationVO;
import com.baoyouqun.entity.CityPartnerApplication;
import com.baoyouqun.mapper.CityPartnerApplicationMapper;
import com.baoyouqun.service.CityPartnerApplicationService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.util.StringUtil;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.io.OutputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;


@Service
public class CityPartnerApplicationServiceImpl extends ServiceImpl<CityPartnerApplicationMapper, CityPartnerApplication> implements CityPartnerApplicationService {

    @Resource
    private CityPartnerApplicationMapper cityPartnerApplicationMapper;

    @Override
    public SingleResponse<CityPartnerApplicationVO> create(CityPartnerApplicationCreateCmd cmd) {
        CityPartnerApplication entity = new CityPartnerApplication();
        entity = ConvertUtils.copyBean(cmd, CityPartnerApplication.class);
        Boolean result = save(entity);
        if (!result) {
            return SingleResponse.buildFailure("100101", "创建失败");
        }

        CityPartnerApplicationVO vo =
                ConvertUtils.copyBean(entity, CityPartnerApplicationVO.class);
        return SingleResponse.of(vo);
    }

    @Override
    public Response update(CityPartnerApplicationUpdateCmd cmd) {
        if (Objects.isNull(cmd)) {
            return Response.buildFailure("100301", "参数不能为空");
        }
        if (StringUtil.isBlank(cmd.getId())) {
            return Response.buildFailure("100302", "ID不能为空");
        }
        CityPartnerApplication oldEntity = getById(cmd.getId());
        if (Objects.isNull(oldEntity)) {
            return Response.buildFailure("100303", "未查询到此数据");
        }
        oldEntity = ConvertUtils.copyBean(cmd, CityPartnerApplication.class);
        Boolean result = updateById(oldEntity);
        if (result) {
            return Response.buildSuccess();
        } else {
            return Response.buildFailure("100304", "更新失败");
        }
    }

    @Override
    public CityPartnerApplicationVO selectById(String id) {
        CityPartnerApplication entity = cityPartnerApplicationMapper.selectById(id);
        CityPartnerApplicationVO vo =
                ConvertUtils.copyBean(entity, CityPartnerApplicationVO.class);
        return vo;
    }

    /**
     * 条件筛选分页查询
     */
    @Override
    public IPage<CityPartnerApplicationVO> pageVo(CityPartnerApplicationQuery query) {
        // 参数初始化：默认未处理、第1页、10条/页
        if (Objects.isNull(query)) {
            query = new CityPartnerApplicationQuery();
        }
        long current = Objects.nonNull(query.getCurrent()) ? query.getCurrent() : 1;
        long size = Objects.nonNull(query.getSize()) ? query.getSize() : 10;

        // 构建分页+筛选条件
        Page<CityPartnerApplication> page = new Page<>(current, size);
        LambdaQueryWrapper<CityPartnerApplication> wrapper = buildQueryWrapper(query);

        // 分页查询+VO转换
        page = this.page(page, wrapper);
        List<CityPartnerApplicationVO> voList = ConvertUtils.copyBeanList(page.getRecords(), CityPartnerApplicationVO.class);
        fillVoStatusDesc(voList); // 批量补充状态描述

        // 封装分页结果
        Page<CityPartnerApplicationVO> voPage = new Page<>(current, size, page.getTotal());
        voPage.setRecords(voList);
        return voPage;
    }

    /**
     * 导出Excel（按筛选条件全量导出）
     */
    @Override
    public void exportApplicationExcel(CityPartnerApplicationQuery query, HttpServletResponse response) {
        // 全量查询配置：第1页+最大条数
        if (Objects.isNull(query)) {
            query = new CityPartnerApplicationQuery();
        }
        query.setCurrent(1L);
        query.setSize(Long.MAX_VALUE);

        try {
            // 1. 查询全量数据
            LambdaQueryWrapper<CityPartnerApplication> wrapper = buildQueryWrapper(query);
            List<CityPartnerApplication> entityList = this.list(wrapper);
            if (CollUtil.isEmpty(entityList)) {
                throw new RuntimeException("无符合条件的申请记录，无法导出");
            }

            // 2. 转换VO+补充状态描述
            List<CityPartnerApplicationVO> voList = ConvertUtils.copyBeanList(entityList, CityPartnerApplicationVO.class);
            fillVoStatusDesc(voList);

            // 3. 创建Excel工作簿
            Workbook workbook = new XSSFWorkbook();
            Sheet sheet = workbook.createSheet("城市合伙人申请记录");
            sheet.setDefaultColumnWidth(20); // 优化列宽

            // 4. 表头样式（加粗+居中）
            CellStyle headerStyle = createHeaderStyle(workbook);
            String[] headers = {"申请人", "手机号", "所在行业", "申请原因", "申请时间", "处理状态"};

            // 5. 写入表头
            Row headerRow = sheet.createRow(0);
            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
                cell.setCellStyle(headerStyle);
            }

            // 6. 填充数据行
            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            for (int i = 0; i < voList.size(); i++) {
                CityPartnerApplicationVO vo = voList.get(i);
                Row dataRow = sheet.createRow(i + 1);
                fillDataRow(dataRow, vo, dtf);
            }

            // 7. 设置下载响应头（解决中文乱码）
            setExcelResponseHeader(response, "城市合伙人申请记录");

            // 8. 输出Excel流
            try (OutputStream outputStream = response.getOutputStream()) {
                workbook.write(outputStream);
                outputStream.flush();
            } finally {
                workbook.close(); // 释放资源
            }

        } catch (IOException e) {
            log.error("导出Excel IO异常", e);
            throw new RuntimeException("导出失败：" + e.getMessage());
        } catch (Exception e) {
            log.error("导出Excel未知异常", e);
            throw new RuntimeException("导出异常：" + e.getMessage());
        }
    }

    /**
     * 更新处理状态（事务保证）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response updateStatus(String id, Byte status) {
        // 1. 参数校验
        if (StrUtil.isBlank(id)) {
            return Response.buildFailure("100302", "申请记录ID不能为空");
        }
        if (!Objects.equals(status, (byte) 1) && !Objects.equals(status, (byte) 2)) {
            return Response.buildFailure("100305", "状态不合法（仅支持1-未处理/2-已处理）");
        }

        // 2. 校验记录存在性
        CityPartnerApplication entity = getById(id);
        if (Objects.isNull(entity)) {
            return Response.buildFailure("100303", "未查询到申请记录");
        }

        // 3. 状态未变化则直接返回
        if (Objects.equals(entity.getStatus(), status)) {
            String desc = status == 1 ? "未处理" : "已处理";
            return Response.buildSuccess();
        }

        // 4. 更新状态+时间
        entity.setStatus(status);
        entity.setUpdateTime(LocalDateTime.now());
        boolean success = updateById(entity);

        // 5. 返回结果
        String desc = status == 1 ? "未处理" : "已处理";
        return success ? Response.buildSuccess() : Response.buildFailure("100304", "状态更新失败");
    }

    // ---------------------- 工具方法（复用逻辑） ----------------------

    /**
     * 构建筛选条件（申请人+手机号+状态）
     */
    private LambdaQueryWrapper<CityPartnerApplication> buildQueryWrapper(CityPartnerApplicationQuery query) {
        LambdaQueryWrapper<CityPartnerApplication> wrapper = new LambdaQueryWrapper<>();
        // 申请人模糊匹配
        if (StrUtil.isNotBlank(query.getRealName())) {
            wrapper.like(CityPartnerApplication::getRealName, query.getRealName());
        }
        // 手机号模糊匹配
        if (StrUtil.isNotBlank(query.getPhoneNumber())) {
            wrapper.like(CityPartnerApplication::getPhoneNumber, query.getPhoneNumber());
        }
        // 处理状态精确匹配
        if (Objects.nonNull(query.getStatus())) {
            wrapper.eq(CityPartnerApplication::getStatus, query.getStatus());
        }
        // 按申请时间倒序（最新在前）
        wrapper.orderByDesc(CityPartnerApplication::getCreateTime);
        return wrapper;
    }

    /**
     * 单个VO补充状态中文描述
     */
    private void fillVoStatusDesc(CityPartnerApplicationVO vo) {
        if (Objects.isNull(vo)) {
            return;
        }
        String desc = switch (Objects.requireNonNullElse(vo.getStatus(), (byte) 0)) {
            case 1 -> "未处理";
            case 2 -> "已处理";
            default -> "未知状态";
        };
        vo.setStatusDesc(desc);
    }

    /**
     * 批量VO补充状态中文描述
     */
    private void fillVoStatusDesc(List<CityPartnerApplicationVO> voList) {
        if (CollUtil.isEmpty(voList)) {
            return;
        }
        voList.forEach(this::fillVoStatusDesc);
    }

    /**
     * 创建Excel表头样式（加粗+居中+边框）
     */
    private CellStyle createHeaderStyle(Workbook workbook) {
        CellStyle style = workbook.createCellStyle();
        Font font = workbook.createFont();
        font.setBold(true);
        style.setFont(font);
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        // 边框优化（可选）
        style.setBorderTop(BorderStyle.THIN);
        style.setBorderBottom(BorderStyle.THIN);
        style.setBorderLeft(BorderStyle.THIN);
        style.setBorderRight(BorderStyle.THIN);
        return style;
    }

    /**
     * 填充Excel数据行
     */
    private void fillDataRow(Row dataRow, CityPartnerApplicationVO vo, DateTimeFormatter dtf) {
        // 申请人（空值处理）
        dataRow.createCell(0).setCellValue(StrUtil.blankToDefault(vo.getRealName(), "未知申请人"));
        // 手机号
        dataRow.createCell(1).setCellValue(StrUtil.blankToDefault(vo.getPhoneNumber(), "未知手机号"));
        // 所在行业
        dataRow.createCell(2).setCellValue(StrUtil.blankToDefault(vo.getIndustry(), "未填写"));
        // 申请原因
        dataRow.createCell(3).setCellValue(StrUtil.blankToDefault(vo.getApplicationReason(), "无"));
        // 申请时间（格式化）
        String timeStr = Objects.nonNull(vo.getCreateTime()) ? vo.getCreateTime().format(dtf) : "未知时间";
        dataRow.createCell(4).setCellValue(timeStr);
        // 处理状态
        dataRow.createCell(5).setCellValue(vo.getStatusDesc());
    }

    /**
     * 设置Excel下载响应头（中文文件名+防缓存）
     */
    private void setExcelResponseHeader(HttpServletResponse response, String prefix) {
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        try {
            ExcelTool.setExportFileName(response, "城市合伙人申请记录");

        } catch (Exception e) {
            throw new RuntimeException("文件名编码失败：" + e.getMessage());
        }
        // 禁用缓存（确保最新数据）
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setDateHeader("Expires", 0);
    }
}